home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
CUGUK
/
COMMS
/
C011.ZIP
/
TYPESQ.C
< prev
next >
Wrap
Text File
|
1990-01-19
|
6KB
|
272 lines
/********************************************************************
* C Users Group (U.K) C Source Code Library File CUGLIB.011 *
* Inquiries to: M. Houston, 36 Whetstone Clo. Farquhar Rd. *
* Edgbaston, Birmingham B15 2QN ENGLAND *
********************************************************************
* File name: typesq.c
* Program name: typesq
* Source of file: The Public Domain Software Library.
* Purpose: types a squeezed file.
* Changes: <who what when & why major changes have been made>
********************************************************************/
/*% cc -O -s % -o type
* TYPE - uses typesq.c for 'sqed' files
derived from cnode 'cat', typesq, and others. W. Earnest 5/28/82
Credit to the following and others for parts of the software:
Dick Greenlaw (usq)
Bob Mathias (typesq)
Steve Passe (cnode)
Joe Shannon (cnode)
Chuck Forsberg (Unix version)
*/
char Version[] = {"type revised 7-16-82"};
#include <stdio.h>
/* #include <signal.h> */
#define ERROR (-1)
#define OK 0
#define PATHLEN 128
#define RECOGNIZE 0xFF76 /* unlikely pattern */
#define DLE 0x90 /* repeat byte flag */
#define SPEOF 256 /* special endfile token */
#define NUMVALS 257 /* 256 data values plus SPEOF*/
#define LARGE 30000
struct _sqleaf { /* Decoding tree */
int _children[2]; /* left, right */
};
struct _sqleaf Dnode[NUMVALS - 1];
int early_exit;
FILE *infile;
int Bpos; /* last bit position read */
int Curin; /* last byte value read */
int Repct; /* Number of times to retirn value */
int Value; /* current byte value or EOF */
sexit()
{
early_exit++;
/* signal(SIGINT, sexit); */
}
sequit()
{
putchar('\n');
exit(1);
}
main(p_argc, p_argv)
int p_argc;
char **p_argv;
{
char file[PATHLEN];
register char x;
/* static char stobuf[BUFSIZ]; */
extern sexit();
/* signal(SIGINT, sexit); */
/* signal(SIGQUIT, sequit); */
/* setbuf(stdout, stobuf); */
if (p_argc < 2) {
fprintf(stderr, "Usage: type name ...\n");
exit(1);
}
for (x = 1;x < p_argc;++x) {
fprintf(stderr, "\n\n======================== Listing %s ========================\n",p_argv[x]);
switch (catvalid(file, p_argv[x])) {
case 'q':
switch (qsend(file)) {
case ERROR:
break;
case 'a':
send_text(file);
}
break;
case 'a':
send_text(file); break;
case 'x':
break;
}
}
return (OK);
}
send_text(file)
char *file;
{
register c;
early_exit = 0;
while( ((c = getc(infile)) != EOF) && (!early_exit) )
putchar(c);
fclose(infile);
fflush(stdout);
return (OK);
}
catvalid(pname, name)
char *pname;
char *name;
{
if((infile=fopen(name, "rb"))==NULL) {
fprintf(stderr, "Can't open %s\n", name);
return ERROR;
}
strcpy(pname, name);
return ('q');
}
/*
The following code is primarily from typesq.c and utr.c. Typesq
is a modification of USQ by Dick Greenlaw. Those modifications (usq
to typesq) were made by Bob Mathias, I am responsible for the butchery
done to make it work with cat.
*/
qsend(fname)
char *fname;
{
register i, c;
register char *p;
register int numnodes; /* size of decoding tree */
char origname[PATHLEN]; /* Original file name without drive */
init_cr(); init_huff();
if(portgetw(infile) != RECOGNIZE) { /* Process header */
rewind(infile);
return 'a'; /* not squeezed after all */
}
portgetw(infile); /* discard checksum */
p = origname; /* Get original file name */
do { /* send it to array */
*p = getc(infile);
} while(*p++ != '\0');
numnodes = portgetw(infile);
if(numnodes < 0 || numnodes >= NUMVALS) {
fprintf(stderr, "%s has invalid decode tree size\n", fname);
fclose(infile);
return ERROR;
}
/* Initialize for possible empty tree (SPEOF only) */
Dnode[0]._children[0] = -(SPEOF + 1);
Dnode[0]._children[1] = -(SPEOF + 1);
for(i = 0; i < numnodes; ++i) { /* Get decoding tree from file */
Dnode[i]._children[0] = portgetw(infile);
Dnode[i]._children[1] = portgetw(infile);
}
/* Get translated output bytes and write file */
fprintf(stderr, "\n%s -> %s\n\n",fname,origname);
early_exit = 0;
while( ((c = getcr(infile)) != EOF) && (!early_exit) )
putchar(c);
fclose(infile);
fflush(stdout);
return OK;
}
/*** from utr.c - */
/* initialize decoding functions */
init_cr()
{
Repct = 0;
}
init_huff()
{
Bpos = 99; /* force initial read */
}
/* Get bytes with decoding - this decodes repetition,
* calls getuhuff to decode file stream into byte
* level code with only repetition encoding.
*
* The code is simple passing through of bytes except
* that DLE is encoded as DLE-zero and other values
* repeated more than twice are encoded as value-DLE-count.
*/
int
getcr()
{
register c;
if(Repct > 0) {
/* Expanding a repeated char */
--Repct;
return Value;
} else {
/* Nothing unusual */
if((c = getuhuff()) != DLE) {
/* It's not the special delimiter */
Value = c;
if(Value == EOF)
Repct = LARGE;
return Value;
} else {
/* Special token */
if((Repct = getuhuff()) == 0)
/* DLE, zero represents DLE */
return DLE;
else {
/* Begin expanding repetition */
Repct -= 2; /* 2nd time */
return Value;
}
}
}
}
/* Decode file stream into a byte level code with only
* repetition encoding remaining.
*/
int
getuhuff()
{
register i;
register bitval;
/* Follow bit stream in tree to a leaf*/
i = 0; /* Start at root of tree */
do {
if(++Bpos > 7) {
if((Curin = getc(infile)) == ERROR)
return ERROR;
Bpos = 0;
/* move a level deeper in tree */
i = Dnode[i]._children[1 & Curin];
} else
i = Dnode[i]._children[1 & (Curin >>= 1)];
} while(i >= 0);
/* Decode fake node index to original data value */
i = -(i + 1);
/* Decode special endfile token to normal EOF */
i = (i == SPEOF) ? EOF : i;
return i;
}
/*
* Machine independent getw which always gets bytes in the same order
* as the CP/M version of SQ wrote them
*/
portgetw(f)
FILE *f;
{
register c;
c = getc(f)&0377;
return c + (getc(f)<<8);
}